package com.nodecollege.cloud.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.nodecollege.cloud.common.constants.NCConstants;
import com.nodecollege.cloud.common.exception.UpmsException;
import com.nodecollege.cloud.common.model.BindVO;
import com.nodecollege.cloud.common.model.NCResult;
import com.nodecollege.cloud.common.model.QueryRelationVO;
import com.nodecollege.cloud.common.model.po.UpmsOrg;
import com.nodecollege.cloud.common.model.po.UpmsRole;
import com.nodecollege.cloud.common.model.po.UpmsRoleOrg;
import com.nodecollege.cloud.common.utils.NCUtils;
import com.nodecollege.cloud.dao.mapper.UpmsOrgMapper;
import com.nodecollege.cloud.dao.mapper.UpmsRoleMapper;
import com.nodecollege.cloud.dao.mapper.UpmsRoleOrgMapper;
import com.nodecollege.cloud.service.RoleOrgService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @author LC
 * @date 2020/1/8 18:56
 */
@Service
public class RoleOrgServiceImpl implements RoleOrgService {

    @Autowired
    private UpmsRoleOrgMapper upmsRoleOrgMapper;

    @Autowired
    private UpmsRoleMapper upmsRoleMapper;

    @Autowired
    private UpmsOrgMapper upmsOrgMapper;


    /**
     * 根据组织机构查询角色列表
     *
     * @param query
     * @return
     */
    @Override
    public NCResult<UpmsRole> getRoleListByOrgId(QueryRelationVO<UpmsRole, UpmsOrg> query) {
        NCUtils.nullOrEmptyThrow(query.getEndNode().getOrgId(), new UpmsException("", "组织机构id不能为空！"));
        List<UpmsRole> list = new ArrayList<>();
        Long total = 0L;
        if (NCConstants.INT_NEGATIVE_1.equals(query.getPageSize())) {
            list = upmsRoleMapper.selectRoleListJoinRoleOrg(query.toMap());
            total = NCUtils.isNullOrEmpty(list) ? 0 : Long.parseLong(list.size() + "");
        } else {
            Page page = PageHelper.startPage(query.getPageNum(), query.getPageSize());
            if (query.isSort()) {
                page.setOrderBy(query.getSortKey() + " " + query.getSortDirection());
            }
            list = upmsRoleMapper.selectRoleListJoinRoleOrg(query.toMap());
            total = page.getTotal();
        }
        return NCResult.ok(list, total);
    }

    /**
     * 根据角色信息获取组织机构列表
     *
     * @param query
     * @return
     */
    @Override
    public NCResult<UpmsOrg> getOrgListByRoleId(QueryRelationVO<UpmsRole, UpmsOrg> query) {
        NCUtils.nullOrEmptyThrow(query.getStartNode().getRoleId(), new UpmsException("", "角色id不能为空！"));
        List<UpmsOrg> list = new ArrayList<>();
        Long total = 0L;
        if (NCConstants.INT_NEGATIVE_1.equals(query.getPageSize())) {
            list = upmsOrgMapper.selectOrgListJoinRoleOrg(query.toMap());
            total = NCUtils.isNullOrEmpty(list) ? 0 : Long.parseLong(list.size() + "");
        } else {
            Page page = PageHelper.startPage(query.getPageNum(), query.getPageSize());
            if (query.isSort()) {
                page.setOrderBy(query.getSortKey() + " " + query.getSortDirection());
            }
            list = upmsOrgMapper.selectOrgListJoinRoleOrg(query.toMap());
            total = page.getTotal();
        }
        return NCResult.ok(list, total);
    }

    /**
     * 绑定/解绑角色组织机构关系
     *
     * @param bindVO
     */
    @Override
    public void bindRoleOrg(BindVO bindVO) {
        NCUtils.nullOrEmptyThrow(bindVO.getMainSource(), new UpmsException("-1", "参数错误！"));

        // 已绑定的数据
        UpmsRoleOrg query = new UpmsRoleOrg();
        query.setTenantId(bindVO.getTenantId());
        // 最终保留的数据
        List<UpmsRoleOrg> endList = new ArrayList<>();
        if (bindVO.getMainSource()) {
            NCUtils.nullOrEmptyThrow(bindVO.getSourceIds(), new UpmsException("", "绑定入参有误"));
            query.setRoleId(bindVO.getSourceIds().get(0));
            bindVO.getSourceIds().forEach(orgId -> {
                bindVO.getTargetIds().forEach(memberId -> {
                    UpmsRoleOrg end = new UpmsRoleOrg();
                    end.setOrgId(memberId);
                    end.setRoleId(orgId);
                    end.setTenantId(bindVO.getTenantId());
                    end.setState(NCConstants.INT_1);
                    endList.add(end);
                });
            });
        } else {
            NCUtils.nullOrEmptyThrow(bindVO.getTargetIds(), new UpmsException("", "绑定入参有误"));
            query.setOrgId(bindVO.getTargetIds().get(0));
            bindVO.getTargetIds().forEach(memberId -> {
                bindVO.getSourceIds().forEach(orgId -> {
                    UpmsRoleOrg end = new UpmsRoleOrg();
                    end.setOrgId(memberId);
                    end.setRoleId(orgId);
                    end.setTenantId(bindVO.getTenantId());
                    end.setState(NCConstants.INT_1);
                    endList.add(end);
                });
            });
        }
        List<UpmsRoleOrg> exList = upmsRoleOrgMapper.selectListByRoleOrg(query);

        // 取消绑定的数据
        exList.forEach(ex -> {
            Boolean delFlag = true;
            for (int i = 0; i < endList.size(); i++) {
                if (ex.getRoleId().equals(endList.get(i).getRoleId())
                        && ex.getOrgId().equals(endList.get(i).getOrgId())) {
                    delFlag = false;
                    break;
                }
            }
            if (delFlag) {
                if (NCConstants.INT_0.equals(ex.getState())){
                    throw new UpmsException("", "该关系不能解除！");
                }
                upmsRoleOrgMapper.deleteByPrimaryKey(ex.getRoleOrgId());
            }
        });

        // 新增绑定的数据
        endList.forEach(end -> {
            Boolean addFlag = true;
            for (int i = 0; i < exList.size(); i++) {
                if (end.getRoleId().equals(exList.get(i).getRoleId())
                        && end.getOrgId().equals(exList.get(i).getOrgId())) {
                    addFlag = false;
                    break;
                }
            }
            if (addFlag) {
                upmsRoleOrgMapper.insert(end);
            }
        });
    }
}
